package jdmx.framework.service.patterns.typed;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import org.apache.commons.beanutils.PropertyUtils;

import jdmx.framework.common.Handler;
import jdmx.framework.common.annotations.EntityField;
import jdmx.framework.service.ServiceContext;
import jdmx.library.da.DataRow;
import jdmx.library.da.DataTable;
import jdmx.library.da.Entity;
import jdmx.library.da.EntityList;
import jdmx.library.da.SqlParam;
import jdmx.library.da.SqHelper;
import jdmx.library.da.SqlStatement;
import jdmx.library.info.EntityInfo;

public class Orm extends Handler {
	
	public EntityList getEntityList(DataTable dataTable, EntityInfo entityInfo) {
		EntityList entityList = new EntityList();
		for (DataRow dataRow : dataTable.getRows()) {
			Entity entity = getEntity(dataRow, entityInfo);
			entityList.add(entity);
		} 
        return entityList;
	}

	public Entity getEntity(DataRow dataRow, EntityInfo entityInfo) {
		Entity entity = (Entity) ServiceContext.entityFactory.createInstance(entityInfo.entityName, entityInfo.entityNamespace);
		PropertyDescriptor[] props = PropertyUtils.getPropertyDescriptors(entity);
		for (PropertyDescriptor propertyDescriptor : props) {
			String propertyName = propertyDescriptor.getName();
			Object columnValue = getProperty(propertyName, dataRow);
			try {
				PropertyUtils.setProperty(entity, propertyName, columnValue);
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			} catch (NoSuchMethodException e) {
			}
		}
		return entity;
	}

	public Object getProperty(String propertyName, DataRow dataRow) {
		Object propertyValue = null;
		propertyValue = dataRow.getCell(propertyName).getValue();
		return propertyValue;
	}

	public SqlStatement getSqlStatement(String sql, Entity entity) {
		SqlStatement sqlStatement = new SqlStatement(sql);
		ArrayList<String> paramNames = SqHelper.getParamsFromSql(sql);
		for (String paramName : paramNames) {
			SqlParam sqlParam = getSqlParam(paramName, entity); 
			sqlStatement.paramList.add(sqlParam);
		}
		return sqlStatement;
	}

	public SqlParam getSqlParam(String paramName, Entity entity) {
		Object propertyValue = null;			
		PropertyDescriptor[] props = PropertyUtils.getPropertyDescriptors(entity);
		
		for (PropertyDescriptor propertyDescriptor : props) {
			String propertyName = propertyDescriptor.getName();
			EntityField annotation = propertyDescriptor.getReadMethod().getAnnotation(EntityField.class);
			if (annotation == null) continue;
			if (!(annotation.filter())) continue;
			if (!(propertyName.equalsIgnoreCase(paramName))) continue;
			try {
				propertyValue = PropertyUtils.getProperty(entity, propertyName);
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			} catch (NoSuchMethodException e) {
			}
		}			
		if (propertyValue == null) 
			propertyValue = "%";
		SqlParam sqlParam = new SqlParam(paramName, propertyValue);
		return sqlParam;
	}

}
